package cn.rdtimes.wolfdsp.sdk.util;


import cn.rdtimes.wolfdsp.sdk.ResponseMessage;
import cn.rdtimes.wolfdsp.sdk.TaskState;
import cn.rdtimes.wolfdsp.sdk.exception.NonMasterException;
import cn.rdtimes.wolfdsp.sdk.exception.ResponseCodeException;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 缺省实现http调用
 * 使用httpclient组件,暂时不支持tls加密调用
 *
 * @author BZ
 */
public final class HttpClientUtil {
    private static final CloseableHttpClient httpClient;
    private static final RequestConfig requestConfig;

    static {
        httpClient = HttpClients.createDefault();
        requestConfig = RequestConfig.custom().setSocketTimeout(30_000).setConnectTimeout(10_000)
                .setConnectionRequestTimeout(10_000).setMaxRedirects(3).build();
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                try {
                    httpClient.close();
                } catch (Exception e) {
                    // ignore
                }
            }
        });
    }

    private HttpClientUtil() {
        // nothing
    }

    /**
     * 由任务想服务端汇报状态请求,如果请求code不是成功抛出响应异常
     *
     * @param url           流程url
     * @param jobId         流程id
     * @param taskId        任务id
     * @param state         任务状态,不能为空值
     * @param exceptionInfo 异常信息
     * @param curProgress   当前进度
     * @param outputParams  输出参数
     * @throws Exception 异常
     */
    public static void reportState(String url, String jobId, String taskId, TaskState state,
                                   String exceptionInfo, Integer curProgress,
                                   Map<String, Object> outputParams) throws Exception {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("jobId", jobId);
        requestMap.put("taskId", taskId);
        requestMap.put("state", state.getValue());
        requestMap.put("timestamp", System.currentTimeMillis());
        requestMap.put("exception", exceptionInfo);
        requestMap.put("curProgress", curProgress);
        requestMap.put("outputParams", outputParams);
        Map<String, Object> ret = sendRequest(url, requestMap);
        int code = (int) ret.get("code");
        String msg = ret.get("msg") == null ? null : (String) ret.get("msg");
        if (code == ResponseMessage.NOT_MASTER_SERVER)
            throw new NonMasterException(msg);
        if (code != ResponseMessage.SUCC)
            throw new ResponseCodeException(msg);
    }

    /**
     * 发送请求,Post方法
     *
     * @param url    url
     * @param inptut 输入数据
     * @return 返回错误时抛出异常
     * @throws Exception 失败抛出异常
     */
    private static Map<String, Object> sendRequest(String url, Map<String, Object> inptut) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        StringEntity entity = new StringEntity(JsonUtil.toString(inptut), ContentType.APPLICATION_JSON);
        httpPost.setEntity(entity);
        CloseableHttpResponse response = httpClient.execute(httpPost);
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode >= HttpStatus.SC_OK && statusCode < HttpStatus.SC_MULTIPLE_CHOICES) {
            String respEntity = EntityUtils.toString(response.getEntity());
            System.out.println(respEntity);
            return JsonUtil.toMap(respEntity);
        }
        throw new Exception(response.toString());
    }

}
